package MicroRpc.framework.protocol.dubbo.json;

import MicroRpc.framework.beans.Invoker;
import MicroRpc.framework.protocol.dubbo.protobuf.InvokerProto;
import MicroRpc.framework.protocol.dubbo.protobuf.InvokerUtils;
import MicroRpc.framework.redis.Registry.LocalRegistry;
import MicroRpc.framework.tools.serializable.BytesUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;

public class ServerHandler extends SimpleChannelInboundHandler<InvokerProto.InvokerMsg> {
    private final ConcurrentHashMap<String,Object>instanceBuffer=new ConcurrentHashMap<>(64);
    private final ObjectMapper objectMapper=new ObjectMapper();
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, InvokerProto.InvokerMsg invokerMsg) throws Exception {

        Invoker invoker = InvokerUtils.invokerProto2Invoker(invokerMsg);
        Object o;
        Class impl = LocalRegistry.getImpl(invoker.getInterfaceName());
        if (!instanceBuffer.contains(invoker.getInterfaceName())){
            o = impl.newInstance();
            instanceBuffer.put(invoker.getInterfaceName(),o);
        }else {
            o=instanceBuffer.get(invoker.getInterfaceName());
        }
        Method method = impl.getMethod(invoker.getMethodName(), invoker.getParamsType());
        Object result = method.invoke(o, invoker.getParams());
        String r = objectMapper.writeValueAsString(result);
        ctx.writeAndFlush(r);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }
}
